package com.zhang.gateway.common.model;

import cn.hutool.core.codec.Base64;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.time.Instant;
import java.util.Arrays;

/**
 * description
 *
 * @author zhangFanJun
 * @date 2023-12-04 17:48
 **/
@Slf4j
public class JwtUtils {

    /**
     * jwt 载荷信息 key
     */
    public static final String CLAIM = "info";
    /**
     * 默认秘钥
     */
    public static final String SECRET = "21098";

    /**
     * 生成token
     */
    public static String genToken(String adminId, String info) {

        String secret = SECRET;

        String infoByte = getInfoEncode(info);

        return JWT.create()
                // 发行人，inner,open
                .withIssuer("inner")
                // 受众
                .withAudience(adminId)
                // 主题
                .withSubject("接口鉴权")
                // 有效期（结束时间）
//                .withExpiresAt(DateUtil.offsetHour(new Date(), 2))
                // 有效时间长度
                .withExpiresAt(Instant.ofEpochSecond(60 * 60 * 2))
                // 生成签名的时间
//                .withIssuedAt(new Date())
                // 这里也可以放map来存一个刷新token信息
                .withClaim(CLAIM, infoByte)
//                .withClaim("key","value")
                // 延签，还有一个默认的延签方式，sign()使用base64加密
                .sign(Algorithm.HMAC256(secret));
    }

    private static String getInfoEncode(String info) {
        if (StringUtils.isBlank(info)) {
            info = "{}";
        }
        return Base64.encode(info.getBytes());
    }


    public static String checkToken(String token, String secret) {
        try {
            DecodedJWT verify = JWT.require(Algorithm.HMAC256(secret)).build().verify(token);
            String adminId = verify.getAudience().get(0);
            String infoEncode = verify.getClaim(CLAIM).asString();
            String info = Arrays.toString(Base64.decode(infoEncode));
            return info;
        } catch (SignatureVerificationException signature) {
            log.error("非法token：", signature);
        } catch (TokenExpiredException expired) {
            log.error("过期token：", expired);
        } catch (Exception e) {
            log.error("校验token异常：", e);
        }
        return null;
    }

}
